"""
AI对话引擎
负责调用DeepSeek API生成AI回复
"""

import re
from typing import List, Dict, Optional
from openai import OpenAI

from ..core.models import AIResponse, EmotionType, ConversationContext
from ..utils.logger import get_logger


class AIDialogueEngine:
    """AI对话引擎"""

    def __init__(
        self,
        api_key: str,
        base_url: str = "https://api.deepseek.com",
        model: str = "deepseek-chat",
        system_prompt: str = "你是一个AI虚拟主播。",
        temperature: float = 0.8,
        max_tokens: int = 100,
        timeout: int = 30,
        max_context_length: int = 10
    ):
        """
        初始化AI对话引擎
        
        Args:
            api_key: DeepSeek API密钥
            base_url: API基础URL
            model: 使用的模型名称
            system_prompt: 系统提示词(人设)
            temperature: 回复随机性(0-1)
            max_tokens: 最大token数
            timeout: 请求超时时间(秒)
            max_context_length: 对话上下文长度
        """
        self.api_key = api_key
        self.base_url = base_url
        self.model = model
        self.system_prompt = system_prompt
        self.temperature = temperature
        self.max_tokens = max_tokens
        self.timeout = timeout
        self.max_context_length = max_context_length

        # 初始化OpenAI客户端(DeepSeek兼容OpenAI接口)
        self.client = OpenAI(
            api_key=api_key,
            base_url=base_url,
            timeout=timeout
        )

        # 对话上下文管理
        self.context = ConversationContext(
            conversation_id="main",
            context_window_size=max_context_length
        )

        self.logger = get_logger()

        # 情感关键词映射
        self.emotion_keywords = {
            EmotionType.HAPPY: ['哈哈', '开心', '高兴', '快乐', '嘿嘿', '哇', '太好了', '^_^', '(*^_^*)'],
            EmotionType.SURPRISED: ['哇', '天啊', '真的吗', '不会吧', '震惊', '惊讶', '!', '!!', '什么'],
            EmotionType.CONFUSED: ['嗯？', '什么', '不懂', '疑惑', '???', '这是啥', '为什么'],
            EmotionType.SAD: ['难过', '呜呜', '伤心', '哭', 'T_T', '(╥﹏╥)', '不开心'],
            EmotionType.EXCITED: ['太棒了', '厉害', '牛', '666', '赞', '好耶', '冲', '激动']
        }

    def generate_reply(self, user_message: str, username: str = "观众") -> AIResponse:
        """
        生成AI回复
        
        Args:
            user_message: 用户消息
            username: 用户名
            
        Returns:
            AIResponse对象
        """
        try:
            # 添加用户消息到上下文
            self.context.add_message("user", f"{username}: {user_message}")

            # 构造API请求消息 - 添加特殊指令让AI在回复中提到用户名
            enhanced_system_prompt = self.system_prompt + f"\n\n重要提示：当前正在回复的用户是【{username}】，请在回复中自然地称呼对方的名字，增强互动感和亲和力。例如：'{username}你好'、'嗨{username}'、'{username}说得对'等。"
            
            messages = [
                {"role": "system", "content": enhanced_system_prompt}
            ]
            messages.extend(self.context.get_messages_for_api())

            self.logger.debug(f"正在生成回复,用户: {username}, 消息: {user_message}")

            # 调用DeepSeek API
            response = self.client.chat.completions.create(
                model=self.model,
                messages=messages,
                temperature=self.temperature,
                max_tokens=self.max_tokens
            )

            # 提取回复文本
            reply_text = response.choices[0].message.content.strip()
            
            # 清理特殊字符，避免ChatTTS报错
            reply_text = self._clean_special_chars(reply_text)

            # 添加AI回复到上下文
            self.context.add_message("assistant", reply_text)

            # 检测情感
            emotion = self._detect_emotion(reply_text)

            self.logger.debug(f"生成回复成功: {reply_text} (情感: {emotion.value})")

            return AIResponse(
                text=reply_text,
                emotion=emotion,
                confidence=1.0
            )

        except Exception as e:
            self.logger.error(f"生成AI回复失败: {e}")
            # 返回默认回复
            return self._get_fallback_response()

    def _detect_emotion(self, text: str) -> EmotionType:
        """
        检测文本中的情感
        
        Args:
            text: 文本内容
            
        Returns:
            情感类型
        """
        for emotion, keywords in self.emotion_keywords.items():
            for keyword in keywords:
                if keyword in text:
                    return emotion

        return EmotionType.NEUTRAL
    
    def _clean_special_chars(self, text: str) -> str:
        """
        清理ChatTTS不支持的特殊字符
        
        Args:
            text: 原始文本
            
        Returns:
            清理后的文本
        """
        # ChatTTS不支持的字符映射
        char_map = {
            '！': '!',   # 全角感叹号 -> 半角
            '？': '?',   # 全角问号 -> 半角
            '，': ',',   # 全角逗号 -> 半角
            '。': '.',   # 中文句号 -> 英文句号
            '；': ';',   # 全角分号 -> 半角
            '：': ':',   # 全角冒号 -> 半角
            '“': '"',  # 左双引号
            '”': '"',  # 右双引号
            '‘': "'",  # 左单引号
            '’': "'",  # 右单引号
            '《': '<',  # 左书名号
            '》': '>',  # 右书名号
            '（': '(',  # 全角左括号
            '）': ')',  # 全角右括号
            '、': ',',  # 顿号 -> 逗号
            '…': '...',  # 省略号
        }
        
        cleaned = text
        for old_char, new_char in char_map.items():
            cleaned = cleaned.replace(old_char, new_char)
        
        # 限制连续感叹号和问号，最多2个
        cleaned = re.sub(r'!{3,}', '!!', cleaned)
        cleaned = re.sub(r'\?{3,}', '??', cleaned)
        
        self.logger.debug(f"文本清理: '{text}' -> '{cleaned}'")
        
        return cleaned

    def _get_fallback_response(self) -> AIResponse:
        """
        获取降级回复(API调用失败时使用)
        
        Returns:
            默认的AIResponse对象
        """
        fallback_messages = [
            "嗯嗯,我听到了~",
            "让我想想...",
            "好的呢!",
            "收到~",
            "明白了!"
        ]
        import random
        text = random.choice(fallback_messages)

        return AIResponse(
            text=text,
            emotion=EmotionType.NEUTRAL,
            confidence=0.5
        )

    def reset_context(self):
        """重置对话上下文"""
        self.context = ConversationContext(
            conversation_id="main",
            context_window_size=self.max_context_length
        )
        self.logger.info("对话上下文已重置")

    def get_context_length(self) -> int:
        """获取当前上下文长度"""
        return len(self.context.history)

    def set_system_prompt(self, prompt: str):
        """
        更新系统提示词
        
        Args:
            prompt: 新的系统提示词
        """
        self.system_prompt = prompt
        self.logger.info("系统提示词已更新")


class SensitiveWordFilter:
    """敏感词过滤器"""

    def __init__(self, sensitive_words_file: Optional[str] = None):
        """
        初始化敏感词过滤器
        
        Args:
            sensitive_words_file: 敏感词文件路径
        """
        self.sensitive_words = set()
        self.logger = get_logger()

        if sensitive_words_file:
            self._load_sensitive_words(sensitive_words_file)

    def _load_sensitive_words(self, file_path: str):
        """加载敏感词列表"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                for line in f:
                    word = line.strip()
                    if word:
                        self.sensitive_words.add(word)
            self.logger.info(f"✓ 已加载 {len(self.sensitive_words)} 个敏感词")
        except FileNotFoundError:
            self.logger.warning(f"敏感词文件不存在: {file_path}")
        except Exception as e:
            self.logger.error(f"加载敏感词失败: {e}")

    def filter(self, text: str, replace_char: str = "*") -> str:
        """
        过滤文本中的敏感词
        
        Args:
            text: 原始文本
            replace_char: 替换字符
            
        Returns:
            过滤后的文本
        """
        filtered_text = text

        for word in self.sensitive_words:
            if word in filtered_text:
                filtered_text = filtered_text.replace(word, replace_char * len(word))

        if filtered_text != text:
            self.logger.warning(f"检测到敏感词,已过滤: {text[:20]}...")

        return filtered_text

    def contains_sensitive_word(self, text: str) -> bool:
        """
        检查文本是否包含敏感词
        
        Args:
            text: 文本内容
            
        Returns:
            是否包含敏感词
        """
        for word in self.sensitive_words:
            if word in text:
                return True
        return False
